package com.token.sysflow.service;

import com.token.base.Pl;
import com.token.sql.AbstractTableBean;
import com.token.sql.IntegrateSql;
import com.token.sql.PrepareSql;

import com.token.sysflow.bean.*;

import java.sql.ResultSet;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.token.base.FuncUtil;
import com.token.base.JsonGenerator;
import com.token.sysflow.hander.AppInfo;
import com.token.sysflow.hander.Person;

/**
 * 写流程信息
 *
 * @author 代码创建
 */
public class FlowInfoRead {
    private final FuncUtil F;
    private final IntegrateSql iSql;

    /**
     * @param f
     * @param iSql
     */
    public FlowInfoRead(FuncUtil f, IntegrateSql iSql) {
        F = f;
        this.iSql = iSql;
    }

    /**
     * @param value
     * @param label
     * @return
     */
    private JSONObject getLabelValue(String value, String label) {
        JSONObject appKey = new JSONObject();
        appKey.put("value", value);
        appKey.put("label", label);
        return appKey;
    }

    /**
     * @throws Exception
     */
    public void ReadData(String flowid) throws Exception {
        FlowFlowInfo dao = new FlowFlowInfo(iSql, flowid);
//        System.out.println("--->主线程开始");
        Future<JSONArray> futurePath = this.getPathAsync(dao.getKeyName(), flowid);
        Future<JSONArray> futureStep = this.getStepAsync(dao.getKeyName(), flowid);
        if (dao.isInitRs()) {
//            System.out.println("---->Flow开始");

            F.putJsonData("nodes", JSONObject.parseObject(dao.getJsonNode()));
            dao.setJsonNode("");
            JSONObject json = JsonGenerator.toJson(dao);


            PrepareSql pVth = new PrepareSql(iSql);
            pVth.setPrepare("select FieldName,Value,Label from " + FlowFlowInfoVth.TABLE_NAME + " where FlowId=? order by FieldName");
            pVth.setPstValue(1,dao.getFlowId());
            ResultSet rsVth = pVth.executeQuery();
            joinFieldArray(rsVth, json);
            rsVth.close();

            AppInfo appInfo = new AppInfo(iSql, dao.getAppKeyId());
            json.remove("SysId");
            json.remove("JsonNode");

            if(dao.getSysAddUser().equals(dao.getSysEditUser())){
                Person person = new Person(iSql,dao.getSysId(),dao.getSysAddUser());
                json.put("SysAddUserShow",person.getPersonName());
                json.put("SysEditUserShow",person.getPersonName());
                person.close();
            }else {
                Person person = new Person(iSql, dao.getSysId(), dao.getSysAddUser());
                json.put("SysAddUserShow", person.getPersonName());
                person.close();

                Person person1 = new Person(iSql, dao.getSysId(), dao.getSysEditUser());
                json.put("SysEditUserShow", person1.getPersonName());
                person1.close();
            }

            json.put("AppKeyId", getLabelValue(appInfo.getAppKeyId(), appInfo.getAppDesc()));
            F.putJsonData("flow", json);
            F.putJsonData("steps", futureStep.get());
            F.putJsonData("paths", futurePath.get());

        } else {
            throw new Exception("流程id【" + flowid + "】在系统中不存在！");
        }
//        System.out.println("--->主线程结束");
        dao.close();

    }

    /**
     * @param keyName
     * @param flowId
     * @return
     */
    public Future<JSONArray> getPathAsync(String keyName, String flowId) {
        //创建CompletableFuture对象
        CompletableFuture<JSONArray> futurePath = new CompletableFuture<>();
        new Thread(() -> {
            try {
//                System.out.println("---->getPathAsync开始");
                //在另一个线程中执行计算
                JSONArray array = readDataPath(keyName, flowId);
                //需要长时间计算的任务结束并得出结果时，设置future的返回值
                futurePath.complete(array);
//                System.out.println("---->getPathAsync结束");
            } catch (Exception ex) {
                //抛出异常
                futurePath.completeExceptionally(ex);
            }
        }).start();

        return futurePath;
    }


    /**
     * @param keyName
     * @param flowId
     * @return
     */
    public Future<JSONArray> getStepAsync(String keyName, String flowId) {
        //创建CompletableFuture对象
        CompletableFuture<JSONArray> futurePath = new CompletableFuture<>();
        new Thread(() -> {
            try {
//                System.out.println("---->getStepAsync开始");
                //在另一个线程中执行计算
                JSONArray array = this.readDataStep(keyName, flowId);
                //需要长时间计算的任务结束并得出结果时，设置future的返回值
                futurePath.complete(array);
//                System.out.println("---->getStepAsync结束");
            } catch (Exception ex) {
                //抛出异常
                futurePath.completeExceptionally(ex);
            }
        }).start();

        return futurePath;
    }

    /**
     * @param keyName
     * @param flowid
     * @return
     * @throws Exception
     */
    private JSONArray readDataPath(String keyName, String flowid) throws Exception {
        StringBuffer sql = new StringBuffer(50);
        JSONArray paths = new JSONArray();
        FlowPathInfo dao = new FlowPathInfo(iSql);
        sql.append(dao.selectCode()).append(" where ").append(keyName).append("=?");
        PrepareSql P = new PrepareSql(iSql);
        P.setPrepare(sql);
        P.setPstValue(1, flowid);
        ResultSet rs = P.executeQuery();
        JSONObject json;
        while (rs.next()) {
            dao.initParamToRs(rs);
            json = JsonGenerator.toJson(dao);
            json.remove("SysAddTime");
            json.remove("SysAddUser");
            json.remove("SysEditTime");
            json.remove("SysEditUser");
            json.remove("SysId");
            paths.add(json);
        }
        rs.close();
        P.close();
        dao.close();
        return paths;
    }

    /**
     * @param keyName
     * @param flowid
     * @return
     * @throws Exception
     */
    private JSONArray readDataStep(String keyName, String flowid) throws Exception {
        JSONArray steps = new JSONArray();
        FlowStepBasic basic = new FlowStepBasic(iSql);
        FlowStepControl control = new FlowStepControl(iSql);
        FlowStepSwitchFunc switchFunc = new FlowStepSwitchFunc(iSql);
        FlowStepApprover approver = new FlowStepApprover(iSql);
        FlowStepSubflow subflow = new FlowStepSubflow(iSql);

        FlowStepSubflowSub flowStepSubflowSub = new FlowStepSubflowSub(iSql);
        FlowStepNotifySub flowStepNotifySub = new FlowStepNotifySub(iSql);

        PrepareSql pVth = new PrepareSql(iSql);
        pVth.setPrepare("select FieldName,Value,Label from " + FlowStepApproverVth.TABLE_NAME + " where StepId=? order by FieldName");

        ResultSet rsv;

        JSONObject jsonStep;
        StringBuffer sql = new StringBuffer(50);
        sql.append(basic.selectCode()).append(" where ").append(keyName).append("=?");
        PrepareSql P = new PrepareSql(iSql);
        P.setPrepare(sql);
        P.setPstValue(1, flowid);
        ResultSet rs = P.executeQuery();

        while (rs.next()) {
            basic.initParamToRs(rs);

            jsonStep = JsonGenerator.toJson(basic);

            if (control.initParamToRs(basic.getStepId())) {
                JsonGenerator.toJson(control, jsonStep);
            }

//			开关
            if (switchFunc.initParamToRs(basic.getStepId())) {
                JsonGenerator.toJson(switchFunc, jsonStep);
            }

            //办理人
            if (approver.initParamToRs(basic.getStepId())) {
                JsonGenerator.toJson(approver, jsonStep);
                if(!approver.getApproverFunc().equals("")){
                    String name = iSql.selectData("select RoleName from F_Sys_Role where SysId='"+ Pl.getSysId() +"' and RoleNumber='"+ approver.getApproverFunc()+"'","RoleName");
                    jsonStep.put("ApproverFunc", getLabelValue(approver.getApproverFunc(),name));
                }
            }

            //子流程
            if (subflow.initParamToRs(basic.getStepId())) {
                JsonGenerator.toJson(subflow, jsonStep);
            }

            jsonStep.put("NotifyWay", jsonStep.getString("NotifyWay").split(";"));
            jsonStep.put("Notify", getNotify(flowStepNotifySub, basic.getKeyName(), basic.getStepId())); //知会
            jsonStep.put("SubFlow", getSubFlow(flowStepSubflowSub, basic.getKeyName(), basic.getStepId())); //子流程

            pVth.setPstValue(1, basic.getStepId());
            rsv = pVth.executeQuery();
            joinFieldArray(rsv, jsonStep);
            rsv.close();


            jsonStep.remove("SysAddTime");
            jsonStep.remove("SysAddUser");
            jsonStep.remove("SysEditTime");
            jsonStep.remove("SysEditUser");
            jsonStep.remove("SysId");

            steps.add(jsonStep);
        }
        P.close();
        basic.close();
        approver.close();
        control.close();
        switchFunc.close();
        subflow.close();
        return steps;
    }

    /**
     * @param bean
     * @param fieldName
     * @param stepId
     * @return
     * @throws Exception
     */
    private JSONArray getNotify(AbstractTableBean bean, String fieldName, String stepId) throws Exception {
        JSONArray arr = new JSONArray();
        PrepareSql pVth_N = new PrepareSql(iSql);
        pVth_N.setPrepare("select FieldName,Value,Label from " + FlowStepNotifyVth.TABLE_NAME + " where NotifyID=? order by FieldName");
        PrepareSql ps = new PrepareSql(iSql);
        ps.setPrepare(bean.selectCode().append(" where ").append(fieldName).append("=?"));
        ps.setPstValue(1, stepId);
        ResultSet rs = ps.executeQuery(), rsVth;
        if (rs.next()) {
            JSONObject json;
            do {
                json = new JSONObject();

                json.put("key", rs.getString("NotifyID"));
                json.put("Conditional", rs.getString("Conditional"));
                json.put("ConditionalApi", rs.getString("ConditionalApi"));
                json.put("NotifyContext", rs.getString("NotifyContext"));
                json.put("ExtWay", rs.getString("ExtWay"));
//                json.put("IsInConfig", rs.getString("IsInConfig"));
                json.put("NotifyFieldName", rs.getString("NotifyFieldName"));
                json.put("NotifyObject", rs.getString("NotifyObject"));
                json.put("NotifySubject", rs.getString("NotifySubject"));
                String CreOrApply = rs.getString("CreOrApply");
                if (CreOrApply.equals("")) {
                    json.put("CreOrApply", new JSONArray());
                } else {
                    json.put("CreOrApply", CreOrApply.split(";"));
                }


                pVth_N.setPstValue(1, rs.getString("NotifyID"));
                rsVth = pVth_N.executeQuery();
                joinFieldArray(rsVth, json);
                arr.add(json);
            } while (rs.next());
        }
        rs.close();
        ps.close();
        return arr;
    }


    /**
     * 读取子流程
     *
     * @param bean
     * @param fieldName
     * @param stepId
     * @return
     * @throws Exception
     */
    private JSONArray getSubFlow(AbstractTableBean bean, String fieldName, String stepId) throws Exception {
        JSONArray arr = new JSONArray();

        PrepareSql pVth_sub = new PrepareSql(iSql);
        pVth_sub.setPrepare("select FieldName,Value,Label from " + FlowStepSubflowVth.TABLE_NAME + " where SubFlowID=? order by FieldName");
        PrepareSql ps = new PrepareSql(iSql);
        ps.setPrepare(bean.selectCode().append(" where ").append(fieldName).append("=?"));
        ps.setPstValue(1, stepId);
        ResultSet rs = ps.executeQuery(), rsVth;
        if (rs.next()) {
            JSONObject json;
            do {
                json = new JSONObject();
                json.put("key", rs.getString("SubFlowID"));
                json.put("SubFlowName", rs.getString("SubFlowName"));
                json.put("SubFlowFlag", rs.getString("SubFlowFlag"));
//                json.put("Sortby", rs.getString("Sortby"));
                json.put("SelectSubFlow", rs.getString("SelectSubFlow"));
                json.put("ReturnResult", rs.getString("ReturnResult"));
                pVth_sub.setPstValue(1, rs.getString("SubFlowID"));
                rsVth = pVth_sub.executeQuery();
                joinFieldArray(rsVth, json);
                arr.add(json);
            } while (rs.next());
        }
        rs.close();
        ps.close();
        return arr;
    }

    /**
     * @param rsv
     * @param jsonStep
     * @throws Exception
     */
    private void joinFieldArray(ResultSet rsv, JSONObject jsonStep) throws Exception {
        if (rsv.next()) {
            String name = rsv.getString("FieldName");
            JSONArray list = new JSONArray();
            do {
                // System.out.println("-->" + rsv.getString("FieldName") + ' ' + rsv.getString("Label"));
                if (!name.equals(rsv.getString("FieldName"))) {
                    jsonStep.put(name, list);
                    list = new JSONArray();
                    name = rsv.getString("FieldName");
                }
                JSONObject json = new JSONObject();
                json.put("value", rsv.getString("Value"));
                json.put("label", rsv.getString("Label"));
                list.add(json);
            } while (rsv.next());

            if (list.size() > 0) {
                jsonStep.put(name, list);
            }
        }
    }
}
